package com.podium.generator.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.podium.auth.utils.SecurityUtils;
import com.podium.comment.exceptional.BaseException;
import com.podium.generator.entity.GeneratorColumn;
import com.podium.generator.entity.GeneratorTable;
import com.podium.generator.mapper.GeneratorTableMapper;
import com.podium.generator.service.GeneratorColumnService;
import com.podium.generator.service.GeneratorTableService;
import com.podium.comment.utils.StringUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

/**
 * @author 邵文泽
 * @description 代码生成数据库表服务实现类
 * @date 2025/4/16 11:10
 */
@Slf4j
@Service
public class GeneratorTableServiceImpl extends ServiceImpl<GeneratorTableMapper, GeneratorTable> implements GeneratorTableService {

    @Resource
    private GeneratorTableMapper generatorTableMapper;
    @Resource
    private GeneratorColumnService generatorColumnService;

    private static final String[] COLUMN_TYPE_STR = {"char", "varchar", "nvarchar", "varchar2", "nvarchar2", "text", "ntext"};
    private static final String[] COLUMN_TYPE_LONG = {"bigint", "int", "tinyint", "smallint", "mediumint", "number"};
    private static final String[] COLUMN_TYPE_BIG_DECIMAL = {"double", "float", "decimal", "real", "decimal", "money", "smallmoney"};
    private static final String[] COLUMN_TYPE_TIME = {"datetime", "date", "time", "year", "timestamp"};
    private static final String[] EXCLUDE_INSERTS = {"id", "create_by", "create_time", "update_by", "update_time", "del_flag"};
    private static final String[] EXCLUDE_UPDATES = {"id", "create_by", "create_time", "update_by", "update_time", "del_flag"};
    private static final String[] EXCLUDE_QUERIES = {"id", "create_by", "create_time", "update_by", "update_time", "del_flag" , "remark"};
    private static final String[] EXCLUDE_LIST = {"id", "create_by", "update_by", "del_flag"};

    @Override
    public IPage<GeneratorTable> databaseTables(Page<GeneratorTable> generatorTablePage, String tableName) {
        return generatorTableMapper.databaseTables(generatorTablePage, tableName);
    }

    @Override
    public boolean exportDatabaseTables(List<String> tableNames) {
        try {
            // 删除重复数据库表信息
            QueryWrapper<GeneratorTable> generatorTableQueryWrapper = new QueryWrapper<>();
            generatorTableQueryWrapper.lambda().in(GeneratorTable::getTableName, tableNames);
            List<GeneratorTable> generatorTableList = generatorTableMapper.selectList(generatorTableQueryWrapper);
            if (generatorTableList != null) {
                generatorTableList.forEach(generatorTable -> this.removeById(generatorTable.getId()));
            }
            // 查询数据库表信息
            List<GeneratorTable> generatorTables = generatorTableMapper.databaseTablesAll(tableNames.toArray(new String[]{}));
            // 查询数据库表字段信息
            generatorTables.forEach(generatorTable -> {
                generatorTable.setClassName(StringUtils.toCamelCaseClassName(generatorTable.getTableName()));
                this.save(generatorTable);
                List<GeneratorColumn> generatorColumns = generatorColumnService.databaseColumns(generatorTable.getTableName());
                generatorColumns.forEach(generatorColumn -> {
                    generatorColumn.setTableId(generatorTable.getId());
                    initColum(generatorColumn);
                    generatorColumnService.save(generatorColumn);
                });
            });
            return true;
        } catch (Exception e) {
            log.error("导入数据库表失败！", e);
            throw new BaseException("导入数据库表失败！请联系管理员查看");
        }
    }

    @Override
    public IPage<GeneratorTable> page(Page<GeneratorTable> page, String tableName, String tableDescribe) {
        QueryWrapper<GeneratorTable> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(GeneratorTable::getDelFlag, 0)
                .like(StringUtils.hasLength(tableName), GeneratorTable::getTableName, tableName)
                .like(StringUtils.hasLength(tableDescribe), GeneratorTable::getTableDescribe, tableDescribe)
                .orderByDesc(GeneratorTable::getId);
        return page(page, queryWrapper);
    }

    @Override
    public GeneratorTable getById(Long id) {
        GeneratorTable generatorTable = super.getById(id);
        generatorTable.setGeneratorColumn(generatorColumnService.listByTableId(id));
        return generatorTable;
    }

    @Override
    public boolean save(GeneratorTable generatorTable) {
        generatorTable.setDelFlag(0);
        generatorTable.setCreateBy(SecurityUtils.getUsername());
        generatorTable.setCreateTime(LocalDateTime.now());
        return super.save(generatorTable);
    }

    @Override
    public boolean updateById(GeneratorTable generatorTable) {
        generatorTable.setUpdateBy(SecurityUtils.getUsername());
        generatorTable.setUpdateTime(LocalDateTime.now());
        for (GeneratorColumn generatorColumn : generatorTable.getGeneratorColumn()) {
            boolean columnUp = generatorColumnService.updateById(generatorColumn);
            if (!columnUp) {
                log.error("更新表字段失败！{}", generatorColumn.getColumnName());
            }
        }
        return super.updateById(generatorTable);
    }

    @Override
    public void removeById(Long id) {
        super.removeById(id);
        generatorColumnService.removeByTableId(id);
    }

    /**
     * 初始化表字段信息
     *
     * @param generatorColumn 表字段信息
     */
    private static void initColum(GeneratorColumn generatorColumn) {
        if (Arrays.asList(COLUMN_TYPE_STR).contains(generatorColumn.getColumnType())) {
            generatorColumn.setJavaType("String");
            generatorColumn.setDisplayType("input");
        }
        if (Arrays.asList(COLUMN_TYPE_LONG).contains(generatorColumn.getColumnType())) {
            generatorColumn.setJavaType("Long");
            generatorColumn.setDisplayType("inputNumber");
        }
        if (Arrays.asList(COLUMN_TYPE_BIG_DECIMAL).contains(generatorColumn.getColumnType())) {
            generatorColumn.setJavaType("BigDecimal");
            generatorColumn.setDisplayType("inputNumberStep");
        }
        if (Arrays.asList(COLUMN_TYPE_TIME).contains(generatorColumn.getColumnType())) {
            generatorColumn.setJavaType("LocalDateTime");
            generatorColumn.setDisplayType("timePicker");
        }
        generatorColumn.setJavaField(StringUtils.toCamelCase(generatorColumn.getColumnName()));
        if (!Arrays.asList(EXCLUDE_INSERTS).contains(generatorColumn.getColumnName())) {
            generatorColumn.setIsInsert(true);
        }
        if (!Arrays.asList(EXCLUDE_UPDATES).contains(generatorColumn.getColumnName())) {
            generatorColumn.setIsUpdate(true);
        }
        if (!Arrays.asList(EXCLUDE_QUERIES).contains(generatorColumn.getColumnName())) {
            generatorColumn.setIsQuery(true);
            if ("String".equals(generatorColumn.getJavaType())) {
                generatorColumn.setQueryType("LIKE");

            } else if ("Integer".equals(generatorColumn.getJavaType()) ||
                    "Long".equals(generatorColumn.getJavaType()) ||
                    "BigDecimal".equals(generatorColumn.getJavaType())
            ) {
                generatorColumn.setQueryType("=");
            }
        }
        if (!Arrays.asList(EXCLUDE_LIST).contains(generatorColumn.getColumnName())) {
            generatorColumn.setIsList(true);
        }
    }
}
